基于流形距离的聚类算法

在家蹲了一个月照顾小孩,完全被洗脑了,程序代码是神马,能吃么?

今天回来,决定练练脑,瞎看了会儿黎曼几何的入门知识,突然觉得没准儿可以用在聚类上,检索了一下,果然有相关的文章。

找到一篇论文,先试试看。《基于流形距离的聚类算法研究及其应用》 http://download.csdn.net/download/deltatang/7614279

通过流形聚类,主要是要解决一些特殊的情况:比如凹集合。

欧式几何的距离公式做出来的聚类在三维空间基本上是个球。高维空间就是超球。总之,聚类出来的结果很多时候让人感叹:有个球用啊。。。。。。

跳到二维空间看看形象的表示:

而用欧氏距离加上K-Means聚类出来的东东是这样的:


所以,先抄写一段公式:



所以要实现的距离公式就是 流形上的单源最短路径


参考公式加上 dijkstra 算法,实现的代码如下:


from math import *

_inf = float('inf')
_ldist_p = 1.1

def riemann_dist(Xi, Xj) :
    total = 0.0
    for i in range(len(Xi)) :
        total += (Xi[i] - Xj[i]) ** 2
    dist = sqrt(total)

    global _ldist_p
    return pow(_ldist_p, dist) - 1

def euclid_dist(Xi, Xj) :
    total = 0.0
    for i in range(len(Xi)) :
        total += (Xi[i] - Xj[i]) ** 2
    return sqrt(total)

def matrix(vexlist, dist_func) :
    array = []
    size = len(vexlist)
    for i in range(size) :
        vexi = vexlist[i]
        array.append([])
        for j in range(size) :
            if i == j :
                array[i].append(0)
            else :
                dist = dist_func(vexlist[i], vexlist[j])
                array[i].append(dist)
    return array
                

def dijkstra(start, end, matrix) :        
    path = [0]
    size = len(matrix)

    dist = [k for k in matrix[start]]
    
    while True :
        if len(path) > 1 :
            idx = path[-1]
            row = matrix[idx]
            val = dist[idx]
            
            for i in range(size) :
                if i in path :
                    continue
                orig = dist[i]
                caculate = val + row[i]
                if orig > caculate :
                    dist[i] = caculate

        curdist = []
        for i in range(size) :
            if i not in path :
                curdist.append(dist[i])
                
        cur = dist.index(min(curdist))
        path.append(cur)

        if cur == end or len(path) == size - 1 :
            break

    return dist[end]

def manifold_dist(vexlist, start, end) :
    m = matrix(vexlist, riemann_dist)
    return dijkstra(start, end, m)

'''---------------------------main---------------------------'''
if __name__ == '__main__':  
    print euclid_dist((0, 3), (4, 0))
    print riemann_dist((0, 3), (4, 0))

    vexlist = [(0, 0), (1, 1), (2, 2)]
    print matrix(vexlist, riemann_dist)

    m = [[0, _inf, 10, _inf, 30, 100],
         [_inf, 0, 5, _inf, _inf, _inf],
         [10, 5, 0, _inf, 50, _inf, _inf],
         [_inf, _inf, 50, 0, 20, 10],
         [30, _inf, _inf, 20, 0, 60],
         [100, _inf, _inf, 10, 60, 0]
         ]
    print dijkstra(0, 3, m)
    print manifold_dist(vexlist, 0, 2)

关于dijkstra的实现,看这里看这里 http://www.cppblog.com/eryar/archive/2013/01/01/196897.html


当然,完成了距离公式,还得往k-means里面套,

关于k-means, 看这里看这里 http://www.daniweb.com/software-development/python/threads/31449/k-means-clustering

英文麻烦?看这里看这里 http://www.blogjava.net/Skynet/archive/2009/08/07/290242.html


下做个记录, 改天有空再来填坑, 毕竟还没验证呢:) 现在该看球咯。荷兰队满赛!

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于流形距离的k-means聚类算法,是一种通过考虑数据点之间的流形距离而进行聚类的方法。在普通的k-means算法中,距离通常是通过欧几里得距离来衡量的。但是,在高维空间中,欧几里得距离存在着维数灾难的问题,这就导致了k-means算法在高维空间中的表现会变得非常差。 为了解决这个问题,基于流形距离的k-means聚类算法距离度量改成了流形距离流形距离是指基于流形结构的距离度量方法,它采用了流形之间的自然连接性质,可以有效地避免维数灾难的问题。在这种方法中,数据点之间的相似性可以通过计算它们在流形上的距离来度量。流形可以被看作是高维空间中的一个低维子空间,因此基于流形距离的k-means算法可以更好地适应高维空间中的数据分布。 基于流形距离的k-means聚类算法的主要步骤与传统的k-means算法基本相同,只是将欧几里得距离换成了流形距离。具体地,该算法首先随机初始化k个聚类中心,然后迭代执行以下步骤:计算每个数据点到不同聚类中心的流形距离,将每个数据点分配到距离其最近的聚类中心所对应的簇中,然后更新每个簇的聚类中心。直到聚类中心的位置不再发生变化为止,算法停止迭代并输出聚类结果。 总之,基于流形距离的k-means聚类算法是一种适应高维空间的数据分布的算法,它通过考虑数据点之间的流形距离来进行聚类,有效避免了维数灾难问题的影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值